

///////////////////////////////////////////////////////
/*
  Project:	CCT
  Platform: STM32
  Author:   Donnie Liang
  Data:     2020.07.01
  Version:  V1.0
  FileName: ChargeUpdate.c

  CopyRight reserved by 


*/


///////////////////////////////////////////////////////


#include   "stdio.h"
#include  <string.h>
//#include  "global.h"

//#include "config.h"

#include "CRC_Check.h"

#include "uart_printf.h"
#include "user_flash.h"   

//#include  "CCT_TopProtocol.h" 

#include 	"ChargeUpdate.h"



 uint8_t  gucFirmware_Upgrade_OK = 0;     //升级校验OK 
 uint32_t gucFirmware_Size;

uint8_t  gucFirmware_CRC32[4];


uint8_t  gucFw_RemainLen   = 0;
uint8_t  gucFw_RemainData[4] ;


#define   FLASH_BUF_SIZE   (1024 )    //2048 // PAGE_SIZE  PAGE_SIZE

//#pragma pack(4)

 uint8_t  OTA_FlashBuff[FLASH_BUF_SIZE];
 uint8_t  APP_FlashBuff[FLASH_BUF_SIZE];

uint16_t  guiOTA_RemainLen   = 0;


//#pragma pack()

uint8_t  gucUpgradingFlag = 0;


void  ChargeUpdateInit(void )
{
    gucUpgradingFlag = 0 ;

}



//  该方法=---文件已经存在则覆盖原来的文件
//返回值 0 创建文件失败，!0创建文件成功
uint8_t UpdateFlash_Create(uint32_t  fw_size)
{	

 FILE * pFile = NULL;
 

	if( fw_size>= APP_Flash_Size  ) 
	{
//#if  ( DEBUG_PRINT_ENABLE || DEBUG_MIN_PRINT_ENABLE   )  
	   printf( "UpdateFlash_Create() fail \n" );  
       printf( "error: fw_size>= APP_Flash_Siz \n" );
//#endif
	  return 0;
	}
		

  //打开文件
   //pFile = fopen ("./user_flash.txt","r+b");//以（读写）形式打开文件    
     pFile = fopen (CCT_APP_FLASH_FILE_PATH,"rb");


  //文件操作
	if (  NULL == pFile)
	{// //打开失败---文件不存在
        pFile = fopen (CCT_APP_FLASH_FILE_PATH,"wb");
		fclose(pFile);

        //UartPrintString( "UpdateFlash_Create() ok \n" );
	    printf( "UpdateFlash_Create() ok path=%s, pFile=%p\n" , CCT_APP_FLASH_FILE_PATH, pFile );  //here 
	}else{

	   printf( "UpdateFlash already Create() path=%s\n" , CCT_APP_FLASH_FILE_PATH );  //here 
       fclose(pFile);
	}

      pFile = NULL;
      return  1;

}




FILE*  OTA_FLASH_Unlock(char* file_name)
{	

	//文件操作
	if (  NULL == file_name )
	{////打开失败---文件不存在
	   logout( "OTA_FLASH_Unlock() fail!\n" );	
	   return NULL;
	}else{ 
	   logout( "OTA_FLASH_Unlock() OK!\n" );	
       return fopen (file_name,"r+b");//以（读写）形式打开文件  
  // return fopen (CCT_APP_FLASH_FILE_PATH,"r+b");//以（读写）形式打开文件      

	}

}


void  OTA_FLASH_Lock(FILE* pFile)
{	
	//文件操作
	if (  NULL != pFile)
	{//
		fclose(pFile); //注：fclose在关闭文件的时候，也会刷新缓冲区	
		pFile = NULL;

	}else{ //打开失败---文件不存在

		UartPrintString( "OTA_FLASH_Lock() fclose fail!\n" );
	}

}







void UpdateFlash_Init(void)
{	

  FILE * pFile = NULL;


  logout( "UpdateFlash_Init ");

    memset(&UpdateData.Buffer[0],0, sizeof( UpdateData_u ) ); //USER_DATA_BUF_MAX

  //打开文件
     pFile = OTA_FLASH_Unlock(CCT_APP_FLASH_FILE_PATH ) ;

  //文件操作
	if (  NULL == pFile)
	{// //打开失败---文件不存在

	    UartPrintString( "fopen ");
		UartPrintString( CCT_APP_FLASH_FILE_PATH);
		UartPrintString( "fail\n" );

	}else{

			ReadDataFromFlash_8Bits(pFile, &UpdateData.Buffer[0],FLASH_UPDATE_DATA_PAGE, sizeof(UpdateData_u ) );  //读取远程升级数据	UPDATE_DATA_BUF_MAX
			if( FLASH_UPDATE_FIRST_WR != UpdateData.Reg.First )		
			{//第一次上电
               // User_DefaultSet( );			

			}
	}
		

  //  fflush(pFile);//刷新缓冲区时，才将输出缓冲区的数据写到文件（磁盘）

 //   fclose(pFile); //注：fclose在关闭文件的时候，也会刷新缓冲区
   
//    pFile = NULL;
     FLASH_Lock( pFile);
	
}






//返回0--集中器没有在升级，非0--集中器正在升级
uint8_t  IsCCT_Upgrading(void )
{
  return  gucUpgradingFlag ;
}


//------非0表示正在升级-----
void  SetCCT_Upgrading( uint8_t flag )
{
    gucUpgradingFlag = flag ;
}




//返回0--写失败，1--写成功
uint8_t   Erase_OTA_Flash(uint32_t  fw_size)
{

FILE* 	pFile;
uint32_t flash_erase_addr ;		
	
	
	if( fw_size>= APP_Flash_Size  ) 
	{

#if  ( DEBUG_PRINT_ENABLE || DEBUG_MIN_PRINT_ENABLE   )  
       printf( "error: fw_size>= APP_Flash_Siz \n" );
#endif

	  return 0;
	}
			

	pFile = OTA_FLASH_Unlock( CCT_APP_FLASH_FILE_PATH);

	if(NULL == pFile)
	{

#if  ( DEBUG_PRINT_ENABLE || DEBUG_MIN_PRINT_ENABLE   )  
       printf( "error: OTA_FLASH_Unlock() fail \n" );
#endif		
		return 0;
	}

	
   flash_erase_addr = APP_Backup_Address;	//0x000FE000
	
	while ( flash_erase_addr  < (APP_Backup_Address+APP_Flash_Size)  )
	{		
			if( 0 != Flash_EraseSector(pFile,flash_erase_addr ) )
			{				
				flash_erase_addr += PAGE_SIZE;//0x000FE000---0x00100000-0x001F4000
			}else{ //error
				

#if  ( DEBUG_PRINT_ENABLE || DEBUG_MIN_PRINT_ENABLE   )  
       printf( "error: Flash_EraseSector() fail \n" );
#endif

				return 0;
			    
			}
	}
		
	
  FLASH_Lock( pFile);	
	
	return 1;	
	
}






//------方法2------验证OK- ----------
//对每一帧的固件长度没有要求，任意一帧固件长度可以是任意长度

//返回0--写失败，1--写成功
uint8_t   Write_OTA_Flash(uint8_t* fw_data,uint32_t flash_addr,uint16_t frame_len)
{

FILE* pFile = NULL;

	if( (flash_addr+frame_len) > (APP_Backup_Address+APP_Flash_Size) )
	{
	  return 0;
	}	
	

     pFile = OTA_FLASH_Unlock( CCT_APP_FLASH_FILE_PATH );
	
	if(NULL == pFile)
	{
		return 0;
	}

    WriteDataToFlash_8Bits(pFile,fw_data, flash_addr, frame_len ); 
	
	FLASH_Lock( pFile );

	
return 1;	
	
}	






 void  CheckAPP_APPbk(void);




//Server询问Client固件校验是否正确 A4H
void Set_OTA_Check_Test(void )	
{
// uint8_t cnt;	
// uint8_t cct_id[6];	
uint8_t crc32[4] = { 0 };

CRC32_CTX ctx = { 0 };	

uint16_t fw_cnt,fw_last,fw_totall;
uint32_t src_addr;	

 FILE*  pFile = NULL;	 
	
 //__disable_irq();//关中断   
	
			
	pFile = OTA_FLASH_Unlock(CCT_APP_FLASH_FILE_PATH); 

	if(NULL == pFile)
	{ 
		//校验失败无应答--here BBQ 
		printf("OTA_Check_Fail OTA_FLASH_Unlock() err\n");
		return ;
	}

	
    CRC32_Init(&ctx);
	
	src_addr = APP_Backup_Address;  // 0x000F9000;
	
//  gucFirmware_Size==0x0001F8F4=129268
	gucFirmware_Size=0x0001F904;

	fw_totall = gucFirmware_Size/FLASH_BUF_SIZE;//16-----8192
	fw_last   = gucFirmware_Size%FLASH_BUF_SIZE;//6388
		
		
	for(fw_cnt = 0; fw_cnt < fw_totall ;fw_cnt++ ) //
	{					
			ReadDataFromFlash_8Bits(pFile, OTA_FlashBuff,src_addr, FLASH_BUF_SIZE);	//here BBQ --0x1FFF09F6  

			CRC32_Update(&ctx, OTA_FlashBuff, FLASH_BUF_SIZE );
		
			src_addr += FLASH_BUF_SIZE;//0x0806F800--0x0803A800
		
	}	

			
	if( 0 != fw_last )
	{			
			ReadDataFromFlash_8Bits(pFile,OTA_FlashBuff,src_addr, fw_last);	//0x08057800  0xff  
			CRC32_Update(&ctx, OTA_FlashBuff, fw_last );
			//src_addr += fw_last;		
	}	



    FLASH_Lock(pFile);		
 //__enable_irq();					

	 CRC32_Final(&ctx, crc32);
	 

		 
	if( (crc32[0]== gucFirmware_CRC32[0] )&&(crc32[1]== gucFirmware_CRC32[1] )&&\
		  (crc32[2]== gucFirmware_CRC32[2] )&&(crc32[3]== gucFirmware_CRC32[3] )  )
	{
		
		  gucFirmware_Upgrade_OK = 1;
			//---------ack------------	
		
			//------检测接收固件的校验---------------
			
	}else{  //校验失败无应答--here BBQ 
	
	
	}


	
}


















